package com.itheima.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.dubbo.api.QuestionApi;
import com.itheima.dubbo.api.UserApi;
import com.itheima.dubbo.api.UserInfoApi;
import com.itheima.dubbo.api.mongo.*;
import com.itheima.server.interceptor.UserHolder;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.model.domain.Question;
import com.tanhua.model.domain.User;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.dto.RecommendQueryDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class TanhuaService {

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @DubboReference
    private UserLikeApi userLikeApi;

    @DubboReference
    private FriendApi friendApi;

    @DubboReference
    private UserApi userApi;

    @DubboReference
    private UserLocationApi userLocationApi;

    @DubboReference
    private VisitorsApi visitorsApi;


    /**
     * 查询今日佳人数据
     *
     * @return
     */
    public TodayBest todayBest() {
        //1、获取用户id
        Long userId = UserHolder.getId();
        //2、调用API查询
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(1l);
            recommendUser.setScore(99d);
        }
        //3、将RecommendUser转化为TodayBest对象
        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
        TodayBest vo = TodayBest.init(userInfo, recommendUser);
        //4、返回
        return vo;
    }


    /**
     * 查询推荐朋友的分页对象
     *
     * @param
     * @return
     */
    public PageResult recommendation(RecommendQueryDto dto) {
        //1. 获取当前登录用户的id,查询分页对象
        Long userId = UserHolder.getId();
        Integer pageNum = dto.getPage();
        Integer pagesize = dto.getPagesize();
        //当前PageResult里面存储的对象其实是RecommendUser
        PageResult pageResult = recommendUserApi.queryRecommendUser(userId, pageNum, pagesize);

        //2.取出pageResult里面Items,遍历推荐用户
        List<RecommendUser> recommendUserList = (List<RecommendUser>) pageResult.getItems();
        //创建一个vo的集合
        List<TodayBest> todayBestList = new ArrayList<>();

        //方式一：每一个推荐的用户都单独远程查询一个UserInfo对象出来，弊端：多次的远程调用会降低效率
       /* for (RecommendUser recommendUser : recommendUserList) {
            //注意：由于当前是远程调用，而现在每次用户信息都需要远程查询一次，会影响效率的。
            //优化的方法：
            UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
            TodayBest todayBest = TodayBest.init(userInfo, recommendUser);
            todayBestList.add(todayBest);
        }*/


        /**
         * 方式二： 批量查询
         */
        //从集合中提取userId出来。
        List<Long> userIds = CollUtil.getFieldValues(recommendUserList, "userId", Long.class);
        //批量查询用户的信息，并且返回一个Map集合    key:23  value:当前用户信息对象
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userIds);
        for (RecommendUser recommendUser : recommendUserList) {
            UserInfo userInfo = userInfoMap.get(recommendUser.getUserId());
            TodayBest todayBest = TodayBest.init(userInfo, recommendUser);
            todayBestList.add(todayBest);
        }
        //修改分页对象里面的items对象
        pageResult.setItems(todayBestList);
        //最终的目标要求pageREsult对象里面存储的是TodayBest
        return pageResult;
    }

    /**
     * 佳人信息
     * @param recommendUserId
     * @return
     */
    public TodayBest personalInfo(Long recommendUserId) {
        //1./查找用户的信息对象
        UserInfo userInfo = userInfoApi.findById(recommendUserId);
        //2 查找当前用户与recommendUserId的Recommend对象
        Long userId = UserHolder.getId();
        RecommendUser recommendUser = recommendUserApi.queryByUserId(userId, recommendUserId);

        //保存访客的记录信息
        Visitors visitors = new Visitors();
        visitors.setUserId(recommendUserId);  //被访问者的id
        visitors.setVisitorUserId(userId); //访问者id
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(recommendUser.getScore());
        visitorsApi.saveOrUpdate(visitors);

        return TodayBest.init(userInfo, recommendUser);
    }

    /**
     * 查询陌生人问题
     * @param userId
     * @return
     */
    public String strangerQuestions(Long userId) {
        Question question = questionApi.findByUserId(userId);
        return question == null ? "你好啊" : question.getTxt();
    }

    /**
     * 回复陌生人问题
     *
     * @param
     * @param reply 发送数据的格式：
     * {"userId":106,"huanXinId":"hx106","nickname":"黑马小妹","strangerQuestion":"你喜欢什么？","reply":"我喜欢你"}
     */
    public void replyQuestions(Long targetUserId, String reply) throws JsonProcessingException {
        Long userId = UserHolder.getId();// 当前的登陆者
        User user = userApi.findById(userId);
        UserInfo userInfo = userInfoApi.findById(userId);
        //查找目标对象的陌生人问题
        Question question = questionApi.findByUserId(targetUserId);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("userId", UserHolder.getId());  //谁给你发送的，谁回答的。
        resultMap.put("huanXinId", user.getHxUser()); //谁给你发送的，谁回答的的环信的id
        resultMap.put("nickname", userInfo.getNickname()); //谁给你发送的，谁回答的的环信的昵称
        resultMap.put("strangerQuestion", question == null ? "节日好" : question.getTxt()); //目标对象的陌生人问题 ,例子：47号阿姨的问题
        resultMap.put("reply", reply); //
        String json = new ObjectMapper().writeValueAsString(resultMap);
        huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + targetUserId, json);
    }


    @Value("${tanhua.default.recommend.users}")
    private String recommendUser;

    /**
     * 作用：获取推荐好友的卡片数据
     * @return
     */
    public List<TodayBest> queryCardsList() {
        //1.查看mongodb查询推荐的人
        Long userId = UserHolder.getId();
        List<RecommendUser> recommendUserList = recommendUserApi.queryCardsList(userId);
        //2. 如果mongodb没有查询到推荐人列表，那么我们就使用默认的。  List<Recommend>
        if (CollUtil.isEmpty(recommendUserList)) {
            recommendUserList = new ArrayList<>();
            String[] recommendUserArray = recommendUser.split(",");
            for (String recommendUserId : recommendUserArray) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Long.valueOf(recommendUserId));
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                recommendUserList.add(recommendUser);
            }
        }
        //3.获取Recommend的userId得到推荐人的id
        List<Long> recommendUserIds = CollUtil.getFieldValues(recommendUserList, "userId", Long.class);
        //4.批量查询推荐人的userInfo信息
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(recommendUserIds);
        //5.遍历RecommendList,构造出TodayBest
        List<TodayBest> todayBestList = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUserList) {
            UserInfo userInfo = userInfoMap.get(recommendUser.getUserId());
            TodayBest todayBest = TodayBest.init(userInfo, recommendUser);
            todayBestList.add(todayBest);
        }
        //最终:List<TodayBest>
        return todayBestList;
    }

    /**
     * 喜欢
     * @param likeUserId
     */
    public void likeUser(Long likeUserId) {
        //1.在UserLike表插入一条喜欢的记录
        Long userId = UserHolder.getId();
        userLikeApi.save(userId, likeUserId, true);
        //2.检查两者是否相互喜欢
        boolean isEachLove = userLikeApi.eachLove(userId, likeUserId);
        //3.如果是相互喜欢，删除喜欢的记录，人后添加为好友，环信也注册为好友
        if (isEachLove) {
            userLikeApi.deleteEachLove(userId, likeUserId);
            huanXinTemplate.contactUsers(Constants.HX_USER_PREFIX + userId, Constants.HX_USER_PREFIX + likeUserId);
            friendApi.save(userId, likeUserId);
        }
    }

    /**
     * 不喜欢
     * @param likeUserId
     */
    public void notLikeUser(Long likeUserId) {
        //插入一条不喜欢的记录
        Long userId = UserHolder.getId();
        userLikeApi.save(userId, likeUserId, false);
    }

    /**
     * 搜附近
     * @param gender
     * @param distance
     * @return
     */
    public List<NearUserVo> queryNearUser(String gender, Integer distance) {
        //1.查找附近的人 List<Long> 返回的是附近的人的id
        Long userId = UserHolder.getId();
        List<Long> userIds = userLocationApi.queryNearUser(userId, distance);
        //2.批量查询userInfo信息对象
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userIds);

        //3.遍历所有的UserInfo,然后构造Vo对象
        List<NearUserVo> voList = new ArrayList<>();
        for (UserInfo userInfo : userInfoMap.values()) {
            if (userInfo.getGender().equalsIgnoreCase(gender) && userInfo.getId() != userId) {
                NearUserVo vo = NearUserVo.init(userInfo);
                voList.add(vo);
            }
        }
        return voList;
    }
}

